"""
会话管理服务
"""
import uuid
import json
from typing import List, Dict, Optional
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from loguru import logger

from app.models.session import ChatSession, ChatMessage, MessageType
from app.models.user import User


class SessionService:
    """会话管理服务"""
    
    def create_session(
        self, 
        db: Session, 
        user_id: Optional[int] = None,
        system_context: Optional[Dict] = None
    ) -> ChatSession:
        """创建新的聊天会话"""
        try:
            session_id = str(uuid.uuid4())
            
            chat_session = ChatSession(
                session_id=session_id,
                user_id=user_id,
                system_context=json.dumps(system_context) if system_context else None,
                is_active="active"
            )
            
            db.add(chat_session)
            db.commit()
            db.refresh(chat_session)
            
            logger.info(f"创建新会话: {session_id}")
            return chat_session
            
        except Exception as e:
            logger.error(f"创建会话失败: {e}")
            db.rollback()
            raise
    
    def get_session(self, db: Session, session_id: str) -> Optional[ChatSession]:
        """获取会话信息"""
        return db.query(ChatSession).filter(
            ChatSession.session_id == session_id
        ).first()
    
    def add_message(
        self,
        db: Session,
        session_id: str,
        message_type: MessageType,
        content: str,
        metadata: Optional[Dict] = None,
        confidence_score: Optional[float] = None,
        operation_id: Optional[int] = None
    ) -> ChatMessage:
        """添加消息到会话"""
        try:
            # 获取会话
            chat_session = self.get_session(db, session_id)
            if not chat_session:
                raise ValueError(f"会话不存在: {session_id}")
            
            # 创建消息
            message = ChatMessage(
                session_id=chat_session.id,
                message_type=message_type,
                content=content,
                metadata=json.dumps(metadata) if metadata else None,
                confidence_score=confidence_score,
                operation_id=operation_id
            )
            
            db.add(message)
            
            # 更新会话标题（如果是第一条用户消息）
            if message_type == MessageType.USER and not chat_session.title:
                chat_session.title = self._generate_session_title(content)
            
            db.commit()
            db.refresh(message)
            
            logger.info(f"添加消息到会话 {session_id}: {message_type.value}")
            return message
            
        except Exception as e:
            logger.error(f"添加消息失败: {e}")
            db.rollback()
            raise
    
    def get_session_messages(
        self, 
        db: Session, 
        session_id: str,
        limit: Optional[int] = None
    ) -> List[ChatMessage]:
        """获取会话的所有消息"""
        chat_session = self.get_session(db, session_id)
        if not chat_session:
            return []
        
        query = db.query(ChatMessage).filter(
            ChatMessage.session_id == chat_session.id
        ).order_by(ChatMessage.created_at)
        
        if limit:
            query = query.limit(limit)
        
        return query.all()
    
    def get_user_sessions(
        self, 
        db: Session, 
        user_id: int,
        limit: int = 20
    ) -> List[ChatSession]:
        """获取用户的会话列表"""
        return db.query(ChatSession).filter(
            ChatSession.user_id == user_id
        ).order_by(ChatSession.updated_at.desc()).limit(limit).all()
    
    def update_session_status(
        self, 
        db: Session, 
        session_id: str, 
        status: str
    ) -> bool:
        """更新会话状态"""
        try:
            chat_session = self.get_session(db, session_id)
            if not chat_session:
                return False
            
            chat_session.is_active = status
            db.commit()
            
            logger.info(f"更新会话状态: {session_id} -> {status}")
            return True
            
        except Exception as e:
            logger.error(f"更新会话状态失败: {e}")
            db.rollback()
            return False
    
    def delete_session(self, db: Session, session_id: str) -> bool:
        """删除会话"""
        try:
            chat_session = self.get_session(db, session_id)
            if not chat_session:
                return False
            
            # 删除会话（级联删除消息）
            db.delete(chat_session)
            db.commit()
            
            logger.info(f"删除会话: {session_id}")
            return True
            
        except Exception as e:
            logger.error(f"删除会话失败: {e}")
            db.rollback()
            return False
    
    def cleanup_old_sessions(self, db: Session, days: int = 30) -> int:
        """清理旧会话"""
        try:
            cutoff_date = datetime.now() - timedelta(days=days)
            
            # 查找旧会话
            old_sessions = db.query(ChatSession).filter(
                ChatSession.updated_at < cutoff_date,
                ChatSession.is_active == "completed"
            ).all()
            
            count = len(old_sessions)
            
            # 删除旧会话
            for session in old_sessions:
                db.delete(session)
            
            db.commit()
            
            logger.info(f"清理了 {count} 个旧会话")
            return count
            
        except Exception as e:
            logger.error(f"清理旧会话失败: {e}")
            db.rollback()
            return 0
    
    def get_session_statistics(self, db: Session, session_id: str) -> Dict:
        """获取会话统计信息"""
        try:
            chat_session = self.get_session(db, session_id)
            if not chat_session:
                return {}
            
            messages = self.get_session_messages(db, session_id)
            
            user_messages = [m for m in messages if m.message_type == MessageType.USER]
            assistant_messages = [m for m in messages if m.message_type == MessageType.ASSISTANT]
            
            # 计算平均置信度
            confidence_scores = [m.confidence_score for m in assistant_messages if m.confidence_score]
            avg_confidence = sum(confidence_scores) / len(confidence_scores) if confidence_scores else 0
            
            # 计算会话时长
            if messages:
                duration = messages[-1].created_at - messages[0].created_at
                duration_minutes = duration.total_seconds() / 60
            else:
                duration_minutes = 0
            
            return {
                "session_id": session_id,
                "title": chat_session.title,
                "status": chat_session.is_active,
                "created_at": chat_session.created_at.isoformat(),
                "updated_at": chat_session.updated_at.isoformat(),
                "total_messages": len(messages),
                "user_messages": len(user_messages),
                "assistant_messages": len(assistant_messages),
                "average_confidence": round(avg_confidence, 2),
                "duration_minutes": round(duration_minutes, 2)
            }
            
        except Exception as e:
            logger.error(f"获取会话统计失败: {e}")
            return {"error": str(e)}
    
    def search_sessions(
        self, 
        db: Session, 
        user_id: Optional[int] = None,
        keyword: Optional[str] = None,
        limit: int = 20
    ) -> List[ChatSession]:
        """搜索会话"""
        query = db.query(ChatSession)
        
        if user_id:
            query = query.filter(ChatSession.user_id == user_id)
        
        if keyword:
            query = query.filter(
                ChatSession.title.contains(keyword)
            )
        
        return query.order_by(ChatSession.updated_at.desc()).limit(limit).all()
    
    def _generate_session_title(self, first_message: str) -> str:
        """根据第一条消息生成会话标题"""
        # 简单的标题生成逻辑
        title = first_message[:50].strip()
        if len(first_message) > 50:
            title += "..."
        
        # 移除换行符
        title = title.replace("\n", " ").replace("\r", " ")
        
        return title or "新对话"
    
    def export_session(self, db: Session, session_id: str) -> Dict:
        """导出会话数据"""
        try:
            chat_session = self.get_session(db, session_id)
            if not chat_session:
                return {"error": "会话不存在"}
            
            messages = self.get_session_messages(db, session_id)
            
            export_data = {
                "session_info": {
                    "session_id": session_id,
                    "title": chat_session.title,
                    "created_at": chat_session.created_at.isoformat(),
                    "updated_at": chat_session.updated_at.isoformat(),
                    "status": chat_session.is_active
                },
                "messages": [
                    {
                        "type": msg.message_type.value,
                        "content": msg.content,
                        "timestamp": msg.created_at.isoformat(),
                        "confidence_score": msg.confidence_score,
                        "metadata": json.loads(msg.metadata) if msg.metadata else None
                    }
                    for msg in messages
                ],
                "statistics": self.get_session_statistics(db, session_id)
            }
            
            return export_data
            
        except Exception as e:
            logger.error(f"导出会话失败: {e}")
            return {"error": str(e)}
